var rp = require('request-promise');
var logger = require('./logger');
var redisToken = require('./redis-token');

// const TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx909bb9da441014f0&secret=a6bce5a3a85ad1731b194067d0124c22';
const TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx963f345a42b9b68a&secret=767a852fd19b1bd457cdb99ed28ebe81';
// TODO 调优配置
// const EXPIRE_TIME = 3600 * 1.9 * 1000; // token过期时间
// const LIMIT_TIME = 60 * 1000; // token api调用相邻两次间隔时间
const EXPIRE_TIME = 15 * 1000; // token过期时间
const LIMIT_TIME = 3 * 1000; // token api调用相邻两次间隔时间

// 微信token操作
class WxToken {

    constructor() {
        this.token = {
            accessToken: null, // token
            createTime: null, // token创建时间
            expireTime: null // token过期时间
        };
        this.invokeCount = 0; // 调用次数技术
        this.isRefreshing = false; // 是否调用中
    }

    // token获取，返回promise
    async get(force = false, oldToken = null) {

        try {

            if (this.isRefreshing) { // 刷新中，返回null，等待redis token update pub事件通知
                return null;
            }

            const NOW = Date.now();
            if (!force && this.token && (this.token.expireTime > NOW)) { // 本地token在有效期，返回本地token
                if (!oldToken || (oldToken != this.token.accessToken)) { // 如果oldToken存在, 需要oldToken != token
                    return this.token;
                }
            }

            // 本地token不在有效期，准备向微信获取
            this.isRefreshing = true;
            let token = await rp(TOKEN_URL);
            token = JSON.parse(token);
            this.token.createTime = NOW;
            this.token.expireTime = NOW + EXPIRE_TIME;
            this.token.accessToken = token.access_token;
            this.invokeCount++; // 调用微信token api计数.
            this.isRefreshing = false;
            logger.info(`[WeixinToken]  第${this.invokeCount}次从微信获取token: ${JSON.stringify(this.token)}`);

            redisToken.save(this.token);

            return this.token;
        } catch (err) {
            logger.error(`[WeixinToken]  第${this.invokeCount}次从微信获取token失败: ${err}`);
        }

        return null;
    }
}

module.exports = new WxToken(); // 导出单例实现
